/*
 * @file     main.c
 * @brief    source file for setting send data & recv data
 *           G_UART_SendData() demo
 *
 * Change Logs:
 * Date           Author             Version        Notes
 * 2022-03-06     yangzhengfeng      V1.0.0         the first version
 */

/* Includes ------------------------------------------------------------------*/
#include "g_1903.h"
#include "g_sysctrl.h"
#include "amr2wavcode.h"
#include "gkt_debug.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define DEBUG_LOG   (0)
#if DEBUG_LOG == 1
#define PR(...)     gkt_printf(__VA_ARGS__)
#else
#define PR(...) 
#endif
#define AMR_MAGIC_NUMBER            "#!AMR/n"       /*23 21 41 4d 52 0a*/
#define PCM_FRAME_SIZE              160             /*8khz 8000*0.02=160*/
#define MAX_AMR_FRAME_SIZE          32
#define AMR_FRAME_COUNT_PER_SECOND  50
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
int amrEncodeMode[8]            = {4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200};   // amr 编码方式
//static uint8_t amrFormat[6]     = {0x23,0x21,0x41,0x4d,0x52,0x0a};
//static uint8_t chRiffID[4]      = {0x52,0x49,0x46,0x46};
//static uint8_t chRiffFormat[4]  = {0x57,0x41,0x56,0x45};
//static uint8_t chFmtID[4]       = {0x66,0x6D,0x74,0x20};
//static uint8_t chChunkID[4]     = {0x64,0x61,0x74,0x61};
/* Private function prototypes -----------------------------------------------*/
static int32_t rounds(const double x)
{
    return((int)(x+0.5));
}
/**
 * @method caclAMRFrameSize
 * @brief  计算amr包数据大小
 * @param  frameHeader: amr格式包头数据
 * @retval frameSize：amr每帧数据长度
 */
int32_t caclAMRFrameSize(uint8_t frameHeader)
{
    int mode;
    int temp1 = 0;
    int temp2 = 0;
    int frameSize;
    temp1 = frameHeader;
    /*编码方式编号 = 帧头的 3-6 位*/
    temp1 &= 0x78; // 0111-1000
    temp1 >>= 3;
    mode = amrEncodeMode[temp1];    
    /*计算 amr 音频数据帧大小*/
    /*原理 : amr 一帧对应 20ms ，那么一秒有 50 帧的音频数据  (12.2kbs:12200/50 = 30.5 = 31byte,31+1byte帧头 = 32)*/
    temp2 = rounds((double)(((double)mode / (double)AMR_FRAME_COUNT_PER_SECOND) / (double)8));
    frameSize = rounds((double)temp2 + 0.5);
    return frameSize;
}
/**
 * @method DecodeAMRFileToWAVEFile
 * @brief  amr 转 wav 格式文件
 * @param  amrbuf: 输入amr源文件
 * @param  wavebuf: 输出wav源文件
 * @retval nFrameCount：当前解码包数
 */
int32_t DecodeAMRFileToWAVEFile(uint8_t *amrbuf, uint8_t* wavebuf)
{
    int * destate;
    int nFrameCount = 0;
    int stdFrameSize;
    uint16_t i = 0;  
    uint8_t amrFrame[MAX_AMR_FRAME_SIZE];
    int16_t pcmFrame[PCM_FRAME_SIZE];
    uint32_t curFramecnt = 0,curWavFramecnt = 0;  
    /* init decoder */
    destate = Decoder_Interface_init();
		if (NULL == destate) {
			gkt_error("Decoder_Interface_init = NULL\n");
			return 0;
		}
    while(amrbuf[curFramecnt] == 0x3c)
    {
        /*解码amr成wav格式*/
        memset(amrFrame, 0, sizeof(amrFrame));
        memset(pcmFrame, 0, sizeof(pcmFrame));
        amrFrame[0]  = amrbuf[curFramecnt];
        stdFrameSize = caclAMRFrameSize(amrFrame[0]);
        PR("stdFrameSize = %x\n",stdFrameSize);
        for(i = 1;i<stdFrameSize;i++)
        {
            amrFrame[i] = amrbuf[curFramecnt+i];
            PR("amrFrame=%02x\n",amrFrame[i]);
        }
        curFramecnt += 32;
        PR("pAmrFramebuf[%d]=0x%02x\n",curFramecnt,amrbuf[curFramecnt]);
        /*解码一个 AMR 音频帧成 PCM 数据*/
        Decoder_Interface_Decode(destate, amrFrame, pcmFrame, 0);
        for(i=0;i<PCM_FRAME_SIZE;i++)
        {
            wavebuf[curWavFramecnt++] = (uint8_t)(pcmFrame[i]&0xff);
            PR("%02x\n",wavebuf[curWavFramecnt-1]);
            wavebuf[curWavFramecnt++] = (uint8_t)(pcmFrame[i]>>8&0xff);
            PR("%02x\n",wavebuf[curWavFramecnt-1]);          
        }
        nFrameCount++;
    }
    PR("nFrameCount = %d\n",nFrameCount);
    Decoder_Interface_exit(destate);
    return nFrameCount;
}
/**
 * @method DecodeAMRFileToWAVEFilePacket
 * @brief  amr 转 wav 格式文件分包模式
 * @param  destate: 当前帧解码地址
 * @param  amrbuf: 输入amr源文件
 * @param  wavebuf: 输出wav源文件
 * @param  isend: 0：起始帧 1：中间帧 2：结束帧
 * @retval nFrameCount：当前解码包数
 */
int32_t* DecodeAMRFileToWAVEFilePacket(int32_t * destate,uint8_t *amrbuf, uint8_t* wavebuf,uint8_t isend)
{
    int16_t pcmFrame[PCM_FRAME_SIZE];
    uint16_t i = 0,j = 0;
		PR("decode armfile: amrbuf[0]\n", amrbuf[0]);
    if(amrbuf[0] == 0x3c)
    {
        if(isend == 0)
        {
            PR("wav init\n");
            destate = Decoder_Interface_init();
					if (NULL == destate) {
						gkt_error("ERROR: Decoder_Interface_init = NULL\n");
						return NULL;
					}
            Decoder_Interface_Decode(destate, amrbuf, pcmFrame, 0);
            for(i=0,j=0;i<PCM_FRAME_SIZE;i++)
            {
                wavebuf[j] = (uint8_t)(pcmFrame[i]&0xff);
                PR("0x%02x ",wavebuf[j]);
                wavebuf[j+1] = (uint8_t)(pcmFrame[i]>>8&0xff);
                PR("0x%02x ",wavebuf[j+1]);     
                j+=2;
            }
            memset(pcmFrame,0,sizeof(pcmFrame));
            return destate;
        }
        else if(isend == 1)
        {
            Decoder_Interface_Decode(destate, amrbuf, pcmFrame, 0);
            for(i=0,j=0;i<PCM_FRAME_SIZE;i++)
            {
                wavebuf[j] = (uint8_t)(pcmFrame[i]&0xff);
                PR("0x%02x ",wavebuf[j]);
                wavebuf[j+1] = (uint8_t)(pcmFrame[i]>>8&0xff);
                PR("0x%02x ",wavebuf[j+1]);     
                j+=2;
            }
            memset(pcmFrame,0,sizeof(pcmFrame));
            return destate;
        }
        else if(isend == 2)
        {
            Decoder_Interface_Decode(destate, amrbuf, pcmFrame, 0);
            for(i=0,j=0;i<PCM_FRAME_SIZE;i++)
            {
                wavebuf[j] = (uint8_t)(pcmFrame[i]&0xff);
                PR("0x%02x ",wavebuf[j]);
                wavebuf[j+1] = (uint8_t)(pcmFrame[i]>>8&0xff);
                PR("0x%02x ",wavebuf[j+1]);     
                j+=2;
            }
            memset(pcmFrame,0,sizeof(pcmFrame));
            Decoder_Interface_exit(destate);
			destate = NULL;
        }
    }
    return destate; 
}
